#pragma once

#include "exports.hpp"
#include "Message.hpp"
#include "Responses.hpp"




namespace Engine
{
	namespace Debugger
	{
		class ENGINE_DEBUGGER_API Command
			: public Message
		{
		public:

			SHARED(Command);

			/**
			 * Creates a new Command.
			 * The message itself will be tagged with a random generated uuid.
			 */
			Command();
			virtual ~Command();
		};
		///////////////////////////////////////////////////////////////////////////////////////////




		class ENGINE_DEBUGGER_API AttachCommand
			: public Command
		{
		public:

			SHARED(AttachCommand);

			typedef void                 result_type;
			typedef Debugger::Response   response_type;

			/**
			 * @returns the type of this event
			 */
			virtual Type type() const;
		};
		///////////////////////////////////////////////////////////////////////////////////////////




		class ENGINE_DEBUGGER_API ContinueCommand
			: public Command
		{
		public:

			SHARED(ContinueCommand);

			typedef void                 result_type;
			typedef Debugger::Response   response_type;

			/**
			 * @returns the type of this event
			 */
			virtual Type type() const;
		};
		///////////////////////////////////////////////////////////////////////////////////////////




		class ENGINE_DEBUGGER_API PauseCommand
			: public Command
		{
		public:

			SHARED(PauseCommand);

			typedef void                 result_type;
			typedef Debugger::Response   response_type;

			/**
			 * @returns the type of this event
			 */
			virtual Type type() const;
		};
		///////////////////////////////////////////////////////////////////////////////////////////




		class ENGINE_DEBUGGER_API StopCommand
			: public Command
		{
		public:

			SHARED(PauseCommand);

			typedef void                 result_type;
			typedef Debugger::Response   response_type;

			/**
			 * @returns the type of this event
			 */
			virtual Type type() const;
		};
		///////////////////////////////////////////////////////////////////////////////////////////




		class ENGINE_DEBUGGER_API DetachCommand
			: public Command
		{
		public:

			SHARED(DetachCommand);

			typedef void                 result_type;
			typedef Debugger::Response   response_type;

			/**
			 * @returns the type of this event
			 */
			virtual Type type() const;
		};
		///////////////////////////////////////////////////////////////////////////////////////////




		class ENGINE_DEBUGGER_API SetBreakpointCommand
			: public Command
		{
		public:

			SHARED(SetBreakpointCommand);

			typedef void                 result_type;
			typedef Debugger::Response   response_type;

			SetBreakpointCommand();
			SetBreakpointCommand(const std::string& module, const std::string& section, int line, bool set = true);



			/**
			 *@returns the type of this event
			 */
			virtual Type type() const;

			/**
			 * @writes this event into the given stream
			 */
			virtual void store(boostext::iostreams::bin_ostream& stream) const;

			/**
			 * @reads this event from the given stream
			 */
			virtual void restore(boostext::iostreams::bin_istream& stream);

			/**
			 * @returns the module this breakpoint applies to
			 */
			const std::string& module() const;

			/**
			 * @returns the section of code this breakpoint applies to
			 */
			const std::string& section() const;

			/**
			 * @returns the line of the section this breakpoint applies to
			 */
			int line() const;

			/**
			 * Tests if the breakpoint shall be set or unset.
			 */
			bool set() const;

		private:

			std::string   m_module;
			std::string   m_section;
			int           m_line;
			bool          m_set;
		};
		///////////////////////////////////////////////////////////////////////////////////////////




		class ENGINE_DEBUGGER_API GetScriptState
			: public Command
		{
		public:

			SHARED(GetScriptState);

			typedef std::vector<char>     result_type;
			typedef ScriptStateResponse   response_type;

			/**
			 * @returns the type of this message
			 */
			virtual Type type() const;
		};
		///////////////////////////////////////////////////////////////////////////////////////////

		class ENGINE_DEBUGGER_API GetCallstackCommand
			: public Command
		{
		public:

			SHARED(GetCallstackCommand);

			typedef Callstack           result_type;
			typedef CallstackResponse   response_type;

			/**
			 * @returns the type of this event
			 */
			virtual Type type() const;
		};
		///////////////////////////////////////////////////////////////////////////////////////////

		class ENGINE_DEBUGGER_API GetVariableCommand
			: public Command
		{
		public:

			SHARED(GetCallstackCommand);

			typedef void                 result_type;
			typedef Debugger::Response   response_type;

			/**
			 * @returns the type of this event
			 */
			virtual Type type() const;
		};
		///////////////////////////////////////////////////////////////////////////////////////////
	}
	///////////////////////////////////////////////////////////////////////////////////////////////
}
///////////////////////////////////////////////////////////////////////////////////////////////////
